<template>
  <div
    class="message-box"
    v-show="visible"
    ref="messageRef"
    :class="{ [`el-message--${type}`]: type }"
    :style="cssStyle"
  >
    <div class="message-content">
      {{ lastOffset }} | {{ topOffset }}｜{{ bottomOffset }} | {{ height }}
      <span>{{ message }}</span>
    </div>
    <!-- 关闭按钮是否展示 -->
    <img v-if="showClose" @click="visible = false" src="./images/close.png" alt="" />
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, watch, nextTick, computed } from 'vue'
import type { MessageProps } from './types'
import { getLastInstance, getLastBottomOffset } from './method'
const visible = ref(false)
// div的高度
const height = ref(0)
// 获取上一个组件的实例
const prevInstance = getLastInstance()
// 组件实例
const messageRef = ref<HTMLDivElement>()

// 准备默认参数
const props = withDefaults(defineProps<MessageProps>(), {
  duration: 3000,
  type: 'message',
  offset: 20
})

onMounted(async () => {
  // 展示
  visible.value = true
  // 关闭弹框
  startTimer()
  // 下一次dom更新之后在获取 (因为一开始是隐藏的)
  await nextTick()
  // 获取当前组件的高度
  height.value = messageRef.value!.getBoundingClientRect().height
})

// 第一个为0
// 通过调用 getLastBottomOffset 函数并传入 props.id 来获取上一个组件实例的底部偏移量。
const lastOffset = computed(() => getLastBottomOffset(props.id))

// 0+20=20 当前位置 （上一个组件底部的距离+预留的offset（顶部偏移量））
// 该元素的top计算值(获取上一个组件的lastOffset + props.offset(组件距离顶部的高度) ) 作为top
const topOffset = computed(() => lastOffset.value + props.offset)

// 42 + 20 = 62 (为下一个组件预留的位置) 组件高度 + 顶部偏移量
// 这个元素为下一个元素预留的offset, 也就是它最低端的bottom的值
const bottomOffset = computed(() => height.value + topOffset.value)

// 该选素的top值
const cssStyle = computed(() => ({
  top: topOffset.value + 'px'
}))
// 计时关闭弹框
function startTimer() {
  // 为0不关闭
  if (props.duration === 0) return
  setTimeout(() => {
    visible.value = false
  }, props.duration)
}

// 移除节点（组件隐藏后删除结构）
watch(visible, (newValue) => {
  if (!newValue) {
    props.onDestroy()
  }
})
// ++ 当然bottomOffset要给下一个组件使用, 所以说需要暴露出去
defineExpose({
  bottomOffset,
  visible
})
</script>

<style scoped></style>
